Title Banner

Previous Book Contents Book Index Next

Inside Macintosh: QuickDraw GX Printing Extensions and Drivers /
Chapter 2 - Printing Extensions / Developing a Printing Extension


Implementing the Background Picture Extension Functions

This section describes the functions of the background picture printing extension. This extension needs to accomplish the following tasks:

  1. Initialize the environment.
  2. Add a panel to the Print dialog box so that the user can make several choices: whether to enable or disable this extension, which picture to use as the background picture, and at what intensity level to draw the picture on the page.
  3. Respond to events that occur in the panel, such as a mouse click or keypress.
  4. Store the background picture in the spool file along with the document that is being spooled.
  5. Draw the selected background picture on each page of a document that is being despooled.
  6. Deallocate the storage allocated for the background picture shape that was spooled.
  7. Shut down the environment at the end of the program.

Initializing the Extension Environment

The background picture printing extension performs very simple initialization. Its override of the GXInitialize message, BWInitialize, allocates a globals world so that it has the global data needed for a printing extension. The GXInitialize message is described on page 4-43 in the chapter "Printing Messages." The code for the BWInitialize function is shown in Listing 2-6.

Listing 2-6 The BWInitialize override function

OSErr BWInitialize()
{
   OSErr err = noErr;

   err = NewMessageGlobals(A5Size(), A5Init);
   if (!err) err = InitGlobalData();
   return err;
}
The BWInitialize function first sets up an A5 world, which you must do in your extension if you are going to use global data. Setting up an A5 world means setting
the A5 register to reference your global data. The functions A5Size and A5Init are supplied for creating an A5 world.

BWInitialize calls a local function named InitGlobalData to initialize any global variables that are defined by the background picture printing extension. This function is shown in Listing 2-7.

IMPORTANT
You must perform the actual initialization of your global variables in
a function that you call from your override of the GXInitialize message. This is because some compilers optimize code in a way that can invalidate the A5 register. This is why the BWInitialize override function calls the InitGlobalData function to initialize the globals.
Listing 2-7 The InitGlobalData function

OSErr InitGlobalData()
{
   gBackwashShape = nil;
   return noErr;
}
This function initializes the gBackwashShape variable to nil to indicate that it is currently unused.

Adding a Background Picture Panel to the Print Dialog Box

The background picture printing extension adds a panel to the Print dialog box. The placeholders for this panel are defined in the backwash.r resource file; however, several of the values need to be filled in at run time. In the background picture printing extension, the override of the GXJobPrintDialog message, BWJobPrintDialog, performs this operation by calling a local function, SetupPrintPanel, and then forwarding the GXJobPrintDialog message to the rest of the message handlers. The GXJobPrintDialog message is described on page 4-84 in the chapter "Printing Messages." The BWJobPrintDialog function is shown in Listing 2-8.

Listing 2-8 The BWJobPrintDialog override function

OSErr BWJobPrintDialog(gxDialogResult *dlogResult)
{
   OSErr err;
   
   err = SetUpPrintPanel();

   if (!err)
      err = Forward_GXJobPrintDialog(dlogResult);
   
   return err;
}
The local function SetupPrintPanel performs the work of setting up the panel
that the background picture extension adds to the Print dialog box. It uses the
Collection Manager to store and access a BackwashCollection structure. The BackwashCollection structure is defined as shown in Listing 2-9. The Collection Manager is described in Inside Macintosh: QuickDraw GX Environment and Utilities.

Listing 2-9 The BackwashCollection structure

struct BackwashCollection {
   long           intensity;
   unsigned char  addBackwash;
   Boolean        haveFileInfo;
   FSSpec         fileInfo;
};
typedef struct BackwashCollection BackwashCollection;
The fields of this structure are used as follows:

Field Description
intensity
The intensity level (a percentage value) that the user has selected for drawing the background picture on the page.
addBackwash
A value that indicates whether the user has enabled the background picture printing extension.
haveFileInfo
A Boolean value that indicates whether the user has entered a picture filename into the panel.
fileInfo
The file system specification of the picture file that the user chose to use as the background picture.
The SetupPrintPanel function first attempts to access the background picture collection item from the job collection, which is the collection of items maintained by
the Collection Manager for the print job that is printing. If this is the first time that the background picture extension has been accessed, the item is not found, and SetupPrintPanel creates a new item with default values and adds it to the collection. Finally, SetupPrintPanel sets up the panel information for the Dialog Manager and calls the GXSetupDialogPanel function to actually add the panel to the dialog box. The GXSetupDialogPanel function is described on page 5-28 in the chapter "Printing Functions for Message Overrides." The code for the SetupPrintPanel function is shown in Listing 2-10.

Listing 2-10 The SetupPrintPanel function

OSErr SetUpPrintPanel()
{
   OSErr                noErr;
   gxPanelSetupRecord   panelSetupRec;
   BackwashCollection   backwashConfig;

/*
   Get the job collection and then try to find the
   backwash collection item in there.
*/

   jobCollection = GXGetJobCollection(GXGetJob());
   /* call local function to get settings */
   err = GetJobCollectionItem(&backwashConfig, nil,
                  kBackwashCollectionType, kBackwashSettingsID);

/* 
   If the collection item doesn't yet exist, create a new
   item, set it up with default values, and add it to the
   job collection 
*/

   if (err == collectionItemNotFoundErr)
      {
         backwashConfig.addBackwash = kDontAddBackwash;
         backwashConfig.haveFileInfo = false;
         backwashConfig.intensity = kDefaultIntensity;
         strcpy(&backwashConfig.fileInfo.name[1], "none");
         backwashConfig.fileInfo.name[0] =
               strlen(&backwashConfig.fileInfo.name[1]);

         /* call local function to store settings */
         err = StoreJobCollectionItem(&backwashConfig,
                                       sizeof(BackwashCollection),
                                       kBackwashCollectionType,
                                       kBackwashSettingsID, true);
      }

   nrequire(err, GetSettings_Failed);

/*
   Set up the panel: store the ID of the panel resource to use, 
   the resource file in which it is located, and the type of
   panel that is being stored.
*/
   panelSetupRec.panelResId= r_BackwashPanel;   /* resource ID */
   /* resource file */
   panelSetupRec.resourceRefNum = GXGetMessageHandlerResFile();
   panelSetupRec.refCon = 0;              /* not used*/
   panelSetupRec.panelKind = gxExtensionPanel;  /* panel type */
      
   err = GXSetupDialogPanel(&panelSetupRec);

GetSettings_Failed:
   
   return err;
}
SetupPrintPanel returns an error code of type OSErr, which is the same type of function result that is returned by all of the functions that it calls. SetupPrintPanel also uses the error code to detect when it needs to initially add its own item to the
job collection.

WARNING
The size of the items in the job collection is subject to change as QuickDraw GX evolves. For that reason, it is important for you to specify an expected size for each item in your calls to the Collection Manager, rather than specifying nil, which tells the Collection Manager to copy the entire object no matter what its size is. The size that you specify must match the size of the data structure into which the item
is being copied.

Handling an Event in the Background Picture Panel

When a user event occurs in the background picture panel, the background picture printing extension needs to examine the event and determine whether or not to handle it. QuickDraw GX sends the GXHandlePanelEvent message whenever an event occurs in a printing panel. The GXHandlePanelEvent message is described on page 4-85 in the chapter "Printing Messages." Included with the message is a structure of type gxPanelInfoRecord, which is declared as shown in Listing 2-11.

Listing 2-11 The gxPanelInfoRecord structure

struct gxPanelInfoRecord {
   gxPanelEvent panelEvt;  /* the event */
   short panelResId;       /* resource ID of current 'ppnl' res */
   DialogPtr pDlg;         /* pointer to dialog box */
   EventRecord *theEvent;  /* pointer to event */
   short itemHit;          /* actual item number of event */
   short itemCount;        /* number of items before your items */
   short evtAction;        /* the action that occurs after
                               this event is processed */
   short errorStringId;    /* ID of error string */
   gxFormat theFormat;     /* the current format */
   void *refCon;           /* refCon from gxPanelSetupRecord */
};

typedef struct gxPanelInfoRecord gxPanelInfoRecord;
The fields of this structure are described in the section "The Panel Information Structure" on page 4-35 in the chapter "Printing Messages."

Panel events and the way that they are processed are described in Inside Macintosh: QuickDraw GX Printing.

In the background picture printing extension, the override of the GXHandlePanelEvent message, BWHandlePanelEvent, responds to the panel events that are shown inTable 2-4. The list of possible panel events that you can respond to is given in the section "Panel Events" on page 4-36 in the chapter "Printing Messages."
Table 2-4 Panel events handled by the background picture printing extension
ConstantExplanation
gxPanelOpenEvtThe panel is about to open. It needs to be initialized and drawn. The background picture extension responds to this event by initializing the current filename that is displayed in the panel.
gxPanelHitEvtThe user has selected an item in the panel. The background picture extension responds when the user selects the "Select PICT" panel item by replacing the file specification in the job collection with the filename that the user selects.
gxPanelActivateEvtThe dialog box window in which the panel resides has just been activated. The background picture extension responds to this event by activating the picture intensity field.
gxPanelDeactivateEvtThe dialog box window in which the panel resides is about to be deactivated. The background picture extension responds to this event by deactivating the picture intensity field.
gxPanelIconFocusEvtThe focus has changed from the panel to the icon list. The background picture extension responds to this event by deactivating the picture intensity field.
gxPanelPanelFocusEvtThe focus has changed from the icon list to the panel. The background picture extension responds to this event by activating the picture intensity field.

The BWHandlePanelEvent function, which is shown in Listing 2-12, operates as a switch statement that selects the events of interest (those listed in Table 2-4) and provides code to handle each. The gxPanelOpenEvt case is handled by calling a local function, OpenBackwashPanel, which is shown in Listing 2-13 on page 2-24.

Listing 2-12 The BWHandlePanelEvent override function

OSErr BWHandlePanelEvent(gxPanelInfoRecord *panelInfo)
{
   OSErr                err = noErr;
   GrafPtr              oldPort;
   DialogPtr            pDlg;
   StandardFileReply    reply;
   SFTypeList           typeList;
   BackwashCollection   backwashConfig;
   Handle               hItem;
   Rect                 itemRect;
   short                itemType;

   pDlg = panelInfo->pDlg;
   GetPort(&oldPort);
   SetPort(pDlg);
   
   switch (panelInfo->panelEvt)  /* select events of interest */
   {
      /* if the panel is opening, initialize it */
      case gxPanelOpenEvt:
         OpenBackwashPanel(pDlg, panelInfo->itemCount);
         break;

/*
   If the user clicks the Select Picture button, prompt for the
   name of a file to load. If the user selects one, access the
   collection item, move the user's file specification to the
   collection, and replace the old collection item with the
   modified version.
*/
      case gxPanelHitEvt:
         if (panelInfo->itemHit == (panelInfo->itemCount +
                                             d_SelectPicture))
         {
            typeList[0] = 'PICT';
            StandardGetFile(nil, 1, typeList, &reply);
            require(replay.sfGood, UserCancelledFileDialog);

            err = GetJobCollectionItem(&backwashConfig, nil,
                  kBackwashCollectionType, kBackwashSettingsID);

            nrequire(err, GetSettings_Failed);

            backwashConfig.haveFileInfo = true;
            BlockMove(&reply.sfFile,
                      &backwashConfig.fileInfo, sizeof(FSSpec));

            /* replace old collection item with updated version */
            err = StoreJobCollectionItem(&backwashConfig,
                        sizeof(BackwashCollection),
                        kBackwashCollectionType, 
                        kBackwashSettingsID, false);
            nrequire(err, StoreSettings_Failed);

            /* update the filename dialog item */
            GetDItem(panelInfo->pDlg,
                     panelInfo->itemCount +d_FileNameItem,
                     &itemType, &hItem, &itemRect);
            SetIText(hItem, &backwashConfig.fileInfo.name);
         }
         break;

/*
   If the panel is activating or deactivating, or if the focus
   (the section of the dialog box that is active) is changed, 
   either activate or deactivate the picture intensity field.
*/
      case gxPanelActivateEvt:
      case gxPanelDeactivateEvt:
      case gxPanelIconFocusEvt:
      case gxPanelPanelFocusEvt:
         if ((((DialogPeek) pDlg)->editField +1) ==
                           (panelInfo->itemCount +d_intensity))
         {
            if ((panelInfo->panelEvt == gxPanelPanelFocusEvt)
               TEActivate(((DialogPeek) pDlg)->textH);
            else
               TEDeactivate(((DialogPeek) pDlg)->textH);
         }
         break;
   }

UserCancelledFileDialog:
GetSettings_Failed:
StoreSettings_Failed:
   SetPort(oldPort);
   return err;
}
The OpenBackwashPanel function in Listing 2-13 is a local function called by the BWHandlePanelEvent function to initialize the background picture panel when the user opens it. This function performs any initialization of the panel that cannot be performed by 'xdtl' resource specifications, which are described in Inside Macintosh: QuickDraw GX Printing.

Listing 2-13 The OpenBackwashPanel function

/*
   OpenBackwashPanel handles non-'xdtl' item initialization when
   the panel is opened. Note that the items are offset from the
   the value of itemCount, which means that item #5 in the panel
   is accessed by passing the value itemCount+5.
*/

void OpenBackwashPanel(DialogPtr pDlg, short itemCount)
{
   BackwashCollection   backwashConfig;
   Handle               hItem;
   Rect                 itemRect;
   short                itemType;

/*
   Initialize the current filename displayed, based on the
   settings in the backwash collection item.
*/
   
   GetJobCollectionItem(&backwashConfig, nil, 
                  kBackwashCollectionType, kBackwashSettingsID);

   GetDItem(pDlg, itemCount +d_FileNameItem, &itemType,
            &hItem, &itemRect);
   SetIText(hItem, &backwashConfig.fileInfo.name);
}
The OpenBackwashPanel function initializes the dialog box panel by filling in the filename that is stored in its configuration information. It operates by retrieving the configuration information from the job collection and storing the filename from the configuration into the filename item in the panel.

Storing the Background Picture in the Spool File

The background picture printing extension draws the background picture on each page. To do this, it first stores the background picture as a resource in the spool file. It then accesses that resource and applies the picture to each page as the page is being despooled.

To store the picture in the spool file, the background picture printing extension overrides the GXCreateSpoolFile message, which QuickDraw GX sends at the start of spooling a document. The GXCreateSpoolFile message is described on page 4-68 in the chapter "Printing Messages." In the background picture printing extension, the override of GXCreateSpoolFile, BWCreateSpoolFile, is shown in Listing 2-14.

Listing 2-14 The BWCreateSpoolFile override function

OSErr BWCreateSpoolFile(FSSpecPtr anFSSpec, long createOptions,
                        gxSpoolFile *theSpoolFile)
{
   gxGraphicsError      grErr;
   BackwashCollection   backwashConfig;

   /* forward the message so that the spool file is created */
   grErr = (gxGraphicsError) Forward_GXCreateSpoolFile(anFSSpec,
                                    createOptions, theSpoolFile);
   nrequire(grErr, ForwardMessage_Failed);
/*
   Get the collection item and see if extension is enabled and 
   picture file info has been entered. If so, add the background
   picture to the spool file. 
*/

   grErr = (gxGraphicsError) GetJobCollectionItem(&backwashConfig,
               nil, kBackwashCollectionType, kBackwashSettingsID);

   if (!grErr && backwashConfig.addBackwash &&                                    backwashConfig.haveFileInfo)
      grErr = AddBackwash(&backwashConfig.fileInfo,
               (short) backwashConfig.intensity, *theSpoolFile);
   else
      if (grErr == collectionItemNotFoundErr)
         grErr = noErr;

ForwardMessage_Failed:
   return (OSErr) grErr;
}
The BWCreateSpoolFile function first forwards the GXCreateSpoolFile message to allow QuickDraw GX to use the default implementation (or other message handlers
to use their implementations) to create the spool file. BWCreateSpoolFile then calls the local function AddBackwash to read the background picture file and store it in the spool file. The AddBackwash function is shown in Listing 2-15.

Listing 2-15 The AddBackwash function

gxGraphicsError AddBackwash(FSSpecPtr fileInfo,
                           short theIntensity,
                           gxSpoolFile theSpoolFile)
{
   gxGraphicsError   grErr = noErr;
   Rect              pictBounds;
   PicHandle         backwashPict;
                     /* use {1, 1} to mean don't stretch */
   Point             patStretchPoint = {1,1};
   Handle            gxShapeHdl = nil;
   gxShape           gxPictShape;
   short             resAttribs;

   /* load the picture and then convert it to a GX shape */
   backwashPict = LoadAPict(fileInfo);
   require_action(backwashPict, CouldNotLoadPICT,
                                          grErr = nilHandleErr;);

   pictBounds = (*backwashPict)->picFrame;
   gxPictShape = GXNewShape(gxPictureType);  /* picture shape */
   nrequire_action(GXGetGraphicsError(&grErr),
               CouldNotCreateShape, KillPicture(backwashPict););

   GXConvertPICTToShape(backwashPict, gxDefaultOptionsTranslation,
                   &pictBounds, &pictBounds, patStretchPoint,
                   gxPictShape, nil);

   KillPicture(backwashPict);       /* get rid of original */
   nrequire_action(GXGetGraphicsError(&grErr),
            CouldNotConvertShape, GXDisposeShape(gxPictShape););

   /* lighten the picture shape as specified by user */
   grErr = SetShapeIntensity(gxPictShape, theIntensity);
   nrequire_action(grErr, CouldNotSetShapeIntensity,
                                    GXDisposeShape(gxPictShape););

   /* flatten picture shape into handle */
   gxShapeHdl = ShapeToHandle(gxPictShape);
   grErr = (gxGraphicsError) MemError();
   GXDisposeShape(gxPictShape);
   nrequire(grErr, CouldNotFlattenShape);
/*
   Add the picture shape as a resource in the spool file. After
   adding it, mark the resource as "sysHeap, purgeable", so that 
   it won't be loaded into PrinterShare's heap, which is small.
*/
   grErr = Send_GXSpoolResource(theSpoolFile, gxShapeHdl,
                     kBackwashCollectionType, r_BackwashPICTID);
   nrequire_action(grErr, CouldNotAddShape,
                                       DisposHandle(gxShapeHdl););

   resAttribs = GetResAttrs(gxShapeHdl);
   SetResAttrs(gxShapeHdl,
                        resAttribs | resSysHeap | resPurgeable);
   ChangedResource(gxShapeHdl);
   WriteResource(gxShapeHdl);

   /* release the resource-DO NOT call DisposHandle on it */
   ReleaseResource(gxShapeHdl);

CouldNotLoadPICT:
CouldNotCreateShape:
CouldNotConvertShape:
CouldNotSetShapeIntensity:
CouldNotFlattenShape:
CouldNotAddShape:

   return grErr;
}
The AddBackwash function stores the background picture as a resource in the spool file. AddBackwash first calls a local function, LoadAPict, to read a picture file and create a PicHandle for it. The LoadAPict function, which opens the specified file, creates the handle, skips over the file header information, and reads the picture data into the handle. AddBackwash then converts the picture into a QuickDraw GX shape by calling the GXConvertPICTToShape function, which is described in Inside Macintosh: QuickDraw GX Objects.

Once AddBackwash has a shape object that represents the background picture, it calls a local function, SetShapeIntensity, to lighten the background picture to the intensity level selected by the user (in the background picture panel). SetShapeIntensity modifies the transfer object for each shape in the background picture to use blending, which lightens the final picture. The intensity is adjusted to match the value selected by the user.

Finally, AddBackwash flattens the picture shape into a handle by calling the local function ShapeToHandle and adds the flattened shape to the spool file as a resource. The resource is added in the system heap and is marked as purgeable. ShapeToHandle calls the GXFlattenShape function, which is described in Inside Macintosh: QuickDraw GX Objects.

Adding the Background Picture to a Page

The background picture printing extension draws the background picture on each page as the page is being despooled. It does this by overriding the GXDespoolPage message with the BWDespoolPage function, which is shown in Listing 2-16. This function first forwards the GXDespoolPage message, which is described on page 4-75 in the chapter "Printing Messages," so that any other message handlers that are going to modify the page can do so first, which allows the background picture to be drawn using the final shape of the page.

Listing 2-16 The BWDespoolPage function

OSErr BWDespoolPage(gxSpoolFile theSpoolFile, long thePageNum,
    gxFormat theFormat, gxShape *thePage, Boolean *formatChanged)
{
   OSErr                anOSErr;
   gxGraphicsError      grErr;
   Handle               vpListHdl, gxShapeHdl = nil;
   gxRectangle          pBounds;
   Fixed                cx, cy, px, py;
   long                 numViewPorts;
   BackwashCollection   backwashConfig;

/*
   First, forward the message to make sure that the final page
   shape is being despooled.
*/

   anOSErr = Forward_GXDespoolPage (theSpoolFile,
                  thePageNum, theFormat, thePage, formatChanged);
   nrequire((grErr = (gxGraphicsError) anOSErr),
                      ForwardMessage_Failed);

   grErr = GetJobCollectionItem(&backwashConfig, nil,
                  kBackwashCollectionType, kBackwashSettingsID);
   nrequire_action((!grErr && backwashConfig.addBackwash
                     && backwashConfig.haveFileInfo),
                   NotAddingBackwash, grErr = noErr);
/*
   Load the flattened shape resource (the background picture) if
   necessary. This is only needed for the first page because the
   shape reference is stored in a global variable.
*/
   if (gBackwashShape == nil)
      anOsErr = Send_GXDespoolResource(theSpoolFile, 
         kBackwashCollectionType, r_BackwasPICTID, &gxShapeHdl);
   nrequire((grErr = (gxGraphicsError) anOSErr),
             DespoolResource_Failed);
/*
   If necessary, unflatten the background picture shape. Since a 
   view port list is needed for the unflattening, use the current
   page's view port list.
*/
   if (gBackwashShape == nil)    /* first page */
   {
      numViewPorts = GXGetShapeViewPorts(*thePage, nil);
      vpListHdl = TempNewHandle(numViewPorts * sizeof(gxViewPort),
                                 &anOSErr);
      grErr = (gxGraphicsError) anOSErr;
      nrequire_action(grErr, TempNewHandle_Failed,
                        ReleaseResource(gxShapeHdl););
      HLock(vpListHdl);
      GXGetShapeViewPorts(*thePage, (gxViewPort *) *vpListHdl);
      gBackwashShape = HandleToShape(gxShapeHdl, numViewPorts,
                                     (gxViewPort *) *vpListHdl);
      DisposHandle(vpListHdl);/* all done with this */
   
      if (gxShapeHdl)
         ReleaseResource(gxShapeHdl);
      nrequire(GXGetGraphicsError(&grErr), CouldNotSetUpShape);
   }
/*
   Now use the current page format to obtain the page dimensions.
   Use the dimensions and the bounds of the picture shape to 
   center the page. Once the shape is centered, add it behind the
   shapes that constitute the contents of the page.
*/
   GXGetFormatDimensions(theFormat, &pBounds, nil);
   grErr = GXGetJobError(GXGetJob());
   nrequire(grErr, GetFormatDims_Failed);

   cx = pBounds.left + (pBounds.right - pBounds.left) >>1;
   cy = pBounds.top + (pBounds.bottom - pBounds.top) >>1;

   GXGetShapeBounds(gBackwashShape, 0, &pBounds);
   px = pBounds.left + (pBounds.right - pBounds.left) >>1;
   py = pBounds.top + (pBounds.bottom - pBounds.top) >>1;
   GXMoveShapeTo(gBackwashShape, cx-px, cy-py);

   GXSetPictureParts(*thePage, 1, 0, 1, &gBackwashShape,
                                                   nil, nil, nil);
   GXGetGraphicsError(&grErr);

ForwardMessage_Failed:
NotAddingBackwash:
DespoolResource_Failed:
TempNewHandle_Failed:
CouldNotSetUpShape:
GetFormatDims_Failed:

   return grErr;
}
After forwarding the GXDespoolPage message, BWDespoolPage makes sure that the background-picture-configuration collection item is available in the job collection. If the item is not found in the job collection, it means that the background picture panel was never opened because that event triggers the adding of the item to the collection. If the panel was never opened, then the user is printing without dialog boxes, and no background picture is added to the pages. In this case, BWDespoolPage does not return an error because the function did not really fail. This is accomplished in the nrequire_action call, which changes the error code to noErr and branches to the end of the function.

If the background-picture-configuration collection item is found, BWDespoolPage checks to see if the global variable for the background picture shape is nil. If so, BWDespoolPage reads the resource from the spool file and unflattens it into a
picture shape.

Finally, BWDespoolPage centers the background picture shape on the page and adds the shape to the page contents.

Closing the Spool File

When QuickDraw GX finishes with the spooling of a document, it sends the GXCloseSpoolFile message, which is described on page 4-79 in the chapter "Printing Messages." The background picture printing extension overrides this message with the BWCloseSpoolFile function, shown in Listing 2-17, to dispose of the picture shape that it allocated for the background picture.

Listing 2-17 The BWCloseSpoolFile override function

OSErr BWCloseSpoolFile(gxSpoolFile theSpoolFile,
                        long closeOptions)
{
   if (gBackwashShape != nil)
   {
      GXDisposeShape(gBackwashShape);
      gBackwashShape = nil;
   }
   return Forward_GXCloseSpoolFile(theSpoolFile, closeOptions);
}

Shutting Down the Background Picture Extension Environment

When the background picture printing extension is finished, it needs to deallocate the globals that it allocated in its override of the GXInitialize message. In the background picture extension, the override of the GXShutDown message, BWShutDown, calls the DisposeMessageGlobals function to do that deallocation, as shown in Listing 2-18. The GXShutDown message is described on page 4-44 in the chapter "Printing Messages."

Listing 2-18 The BWShutDown override function

OSErr BWShutDown()
{
   DisposeMessageGlobals();
   return noErr;
}

Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996




Navigation graphic, see text links

Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help